package com.maisha.DBUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.maisha.bean.AuditPower;

public class BeanToSql {
	
	private static final Logger log = Logger.getLogger(BeanToSql.class);
	
	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchFieldException{
		AuditPower ap = new AuditPower();
		ap.setBx1("1111111111");
		ap.setName("this is pword name");
		ap.setCode("MGMGMGMGMMG");
		update_Sql(AuditPower.class,ap,true);
	}
	
	/** 根据给定的object生成 insert 语句
	 * @param bc
	 * @param obj
	 * @param constatsNull  当属性值为null 是否作为插入字段
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static <T> String insert_Sql(Class<T> bc, T obj,boolean constatsNull) throws NoSuchFieldException, IllegalAccessException, InvocationTargetException{
		StringBuffer sb = new StringBuffer(SQLConstant.INSERT);
		Field field;
		try {
			field = bc.getField(SQLConstant.TABLE);
			if(field!=null){ //添加biao
				sb.append(field.get(obj));
				sb.append(SQLConstant.LEFT_TAG);
			}
			StringBuffer _column = new StringBuffer();
			StringBuffer _values = new StringBuffer();
			
			Method[] ms = bc.getDeclaredMethods();
			Object result_tmp = null;
			String field_name = null;
			Class<?> fieldtype = null;
			
			for(Method m : ms){
				if(m.getName().startsWith("get")){
					result_tmp = m.invoke(obj, null);
					fieldtype = m.getReturnType();
					//拼装值
					addResultByPro_Value(_values,result_tmp,fieldtype,constatsNull);
					//获得对应的 column 名
					if(constatsNull){
						field_name = getColumnNameByMethod(m.getName());
						if(StringUtils.isNotBlank(field_name)){
							field = bc.getField(field_name);
							_column.append(field.get(obj));
							_column.append(SQLConstant.POINT_TAG);
						}
					}else{
						if(result_tmp!=null){
							field_name = getColumnNameByMethod(m.getName());
							if(StringUtils.isNotBlank(field_name)){
								field = bc.getField(field_name);
								_column.append(field.get(obj));
								_column.append(SQLConstant.POINT_TAG);
							}
						}
					}
				}
			}
			if(_column.length() > 2){
				sb.append(_column.substring(0,_column.length()-2));
			}
			sb.append(SQLConstant.RIGHT_TAG);
			sb.append(SQLConstant.VALUES);
			sb.append(SQLConstant.LEFT_TAG);
			if(_values.length() > 2){
				sb.append(_values.substring(0,_values.length()-2));
			}
			sb.append(SQLConstant.RIGHT_TAG);
			log.info("generate sql : "+sb.toString());
			return sb.toString();
		} catch (SecurityException e) {
			log.error("get sql by object error");
			throw e;
		} catch (NoSuchFieldException e) {
			log.error("get sql by object error");
			throw e;
		} catch (IllegalArgumentException e) {
			log.error("get sql by object error");
			throw e;
		} catch (IllegalAccessException e) {
			log.error("get sql by object error");
			throw e;
		} catch (InvocationTargetException e) {
			log.error("get sql by object error");
			throw e;
		}
	}
	
	/** 根据给定的object生成 update 语句
	 * @param bc
	 * @param obj
	 * @param constatsNull  当属性值为null 是否作为插入字段
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static <T> String update_Sql(Class<T> bc, T obj,boolean constatsNull) throws NoSuchFieldException, IllegalAccessException, InvocationTargetException{
		StringBuffer sb = new StringBuffer(SQLConstant.UPDATE);
		Field field;
		try {
			field = bc.getField(SQLConstant.TABLE);
			if(field!=null){ //添加biao
				sb.append(field.get(obj));
				sb.append(SQLConstant.SET);
			}
			StringBuffer _values = new StringBuffer();
			
			Method[] ms = bc.getDeclaredMethods();
			Object result_tmp = null;
			String field_name = null;
			Class<?> fieldtype = null;
			
			for(Method m : ms){
				if(m.getName().startsWith("get")){
					result_tmp = m.invoke(obj, null);
					fieldtype = m.getReturnType();
					if(constatsNull){
						field_name = getColumnNameByMethod(m.getName());
						field = bc.getField(field_name);
						_values.append(field.get(obj));
						_values.append(SQLConstant.EQSE);
						if(isStringValue(fieldtype)){
							addPoint(_values,result_tmp);
						}else{
							_values.append(result_tmp);
							sb.append(SQLConstant.POINT_TAG);
						}
					}
				}
			}
			if(_values.length() > 2){
				sb.append(_values.substring(0,_values.length()-2));
			}
			System.out.println(sb.toString());
			log.info("generate sql : "+sb.toString());
			return sb.toString();
		} catch (SecurityException e) {
			log.error("get sql by object error");
			throw e;
		} catch (NoSuchFieldException e) {
			log.error("get sql by object error");
			throw e;
		} catch (IllegalArgumentException e) {
			log.error("get sql by object error");
			throw e;
		} catch (IllegalAccessException e) {
			log.error("get sql by object error");
			throw e;
		} catch (InvocationTargetException e) {
			log.error("get sql by object error");
			throw e;
		}
		
	}
	
	
	
	/** 根据 结果 、结果类型 等拼装 记过组成的 插入语句
	 * @param sb
	 * @param value
	 * @param valueType
	 * @param constatsNull
	 */
	private static void addResultByPro_Value(StringBuffer sb,Object result,Class<?> fieldtype,boolean constatsNull){
		
		if(constatsNull){
			if(isStringValue(fieldtype)){
				if(result!=null){
					addPoint(sb,result);
				}else{
					addNullAsResult(sb);
				}
			}else{
				if(result!=null){
					sb.append(result);
					sb.append(SQLConstant.POINT_TAG);
				}else{
					addNullAsResult(sb);
				}
			}
		}else{
			if(isStringValue(fieldtype)){
				if(result!=null){
					addPoint(sb,result);
				}
			}else{
				if(result!=null){
					sb.append(result);
					sb.append(SQLConstant.POINT_TAG);
				}
			}
		}
		
	}
	
	
	/***
	 * 根据方法名称 获得对应的 表字段名称
	 * @param name
	 * @return
	 */
	private static String getNameByGetMethod(String name){
		if(name.contains("get")){
			name = name.replace("get", ""); //去掉get
			name = name.substring(0, 1).toLowerCase()+name.substring(1);
			return name;
		}else{
			return null;
		}
	}
	
	/** 根据 get方法名称 获得 对应的 colum的 属性
	 * @param name
	 * @return
	 */
	private static String getColumnNameByMethod(String name){
		String tmp = getNameByGetMethod(name);
		if(StringUtils.isNotBlank(tmp)){
			return tmp+SQLConstant.TABLE_COLUMN_END;
		}else{
			return null;
		}
	}
	
	/** 判断 结果是否需要加  单引号
	 * @param fieldtype
	 * @return
	 */
	private static boolean isStringValue(Class<?> fieldtype){
		if(fieldtype.toString().contains("Integer")
		||fieldtype.toString().contains("Long")
		||fieldtype.toString().contains("Double")
		||fieldtype.toString().contains("Float")){
			return false;
		}else{
			return true;
		}
	}
	
	/** 将结果 添加单引号 发
	 * @param result
	 * @return
	 */
	private static void addPoint(StringBuffer sb,Object result){
		sb.append(SQLConstant.POINT_TOP_TAG);
		sb.append(result);
		sb.append(SQLConstant.POINT_TOP_TAG);
		sb.append(SQLConstant.POINT_TAG);
	}
	
	/** 将 null 做为结果值插入
	 * @param sb
	 */
	private static void addNullAsResult(StringBuffer sb){
		sb.append("null");
		sb.append(SQLConstant.POINT_TAG);
	}
	
}
